<script setup lang="ts">
import { onBeforeUnmount, onMounted, ref, watch } from 'vue'
import { useDebounceFn, useResizeObserver } from '@vueuse/core'
import echarts from '@/components/ui/lazy-import-echarts'

const props = defineProps({
  id: {
    type: String,
    default: 'chartId',
    required: true,
  },
  options: {
    type: Object,
    default: () => {},
    required: true,
  },
  width: {
    type: String,
    default: '100%',
  },
  height: {
    type: String,
    default: '400px',
  },
})

const emits = defineEmits(['lineClick', 'piecewiseClick', 'dataZoomScroll'])

const scrollPosition = ref({ start: 0, end: 10 })

let chart: any

watch(
  () => props.options,
  (val) => {
    chart.setOption(val)
  },
  { deep: true },
)

function initChart() {
  chart = echarts.init(document.getElementById(props.id) as HTMLDivElement)
  chart.setOption(props.options)

  chart.on('datarangeselected', (param: any) => {
    // 记录scatter分类被选中的项
    emits('piecewiseClick', param)
    // 回填slider滚动值(piecewiseClick触发的时候默认会重置滚动条，因此需要回填)
    emits('dataZoomScroll', scrollPosition.value)
  })

  chart.on('dataZoom', (params: any) => {
    scrollPosition.value = { start: params.start, end: params.end }
    // 记录slider滚动值
    emits('dataZoomScroll', scrollPosition.value)
  })

  chart.on('legendselectchanged', (params: any) => {
    // 记录line图分类被选中的项
    emits('lineClick', params)
  })
}

// 销毁实例
function disposeChart() {
  chart.off('datarangeselected')
  chart.off('dataZoom')
  chart.dispose()
  chart = null
}

// 只清理数据
function cleanChart() {
  chart.clear()
}

const resize = useDebounceFn(() => {
  chart.resize()
}, 0)

onMounted(() => {
  initChart()
  // 视口发生变化-图形区域变化-执行回调chart.resize
  useResizeObserver(document.getElementById(props.id), resize)
})

onBeforeUnmount(() => {
  // 这里一定要做清理工作，不然会造成内存泄漏
  disposeChart()
})

defineExpose({
  disposeChart,
  cleanChart,
})
</script>

<template>
  <div :id="id" :style="{ width, height, margin: '0 auto' }" />
</template>
